From 2acc4cfee703ce6277d28c715553a0071d1ff0df Mon Sep 17 00:00:00 2001 From: "kaf24@freefall.cl.cam.ac.uk" Date: Sat, 16 Oct 2004 23:31:39 +0000 Subject: [PATCH] bitkeeper revision 1.1159.113.2 (4171af5bkubQeHmeCV0gipUrBqdltA) Fix TLB coherency bug in map_domain_mem, as pointed out by Michael Fetterman. --- xen/arch/x86/x86_32/domain_page.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/xen/arch/x86/x86_32/domain_page.c b/xen/arch/x86/x86_32/domain_page.c index 23b29a0c6c..e261d4cb40 100644 --- a/xen/arch/x86/x86_32/domain_page.c +++ b/xen/arch/x86/x86_32/domain_page.c @@ -19,7 +19,7 @@ #include unsigned long *mapcache; -static unsigned int map_idx, shadow_map_idx[NR_CPUS]; +static unsigned int map_idx, epoch, shadow_epoch[NR_CPUS]; static spinlock_t map_lock = SPIN_LOCK_UNLOCKED; /* Use a spare PTE bit to mark entries ready for recycling. */ @@ -30,11 +30,11 @@ static void flush_all_ready_maps(void) unsigned long *cache = mapcache; /* A bit skanky -- depends on having an aligned PAGE_SIZE set of PTEs. */ - do { if ( (*cache & READY_FOR_TLB_FLUSH) ) *cache = 0; } + do { + if ( (*cache & READY_FOR_TLB_FLUSH) ) + *cache = 0; + } while ( ((unsigned long)(++cache) & ~PAGE_MASK) != 0 ); - - perfc_incrc(domain_page_tlb_flush); - local_flush_tlb(); } @@ -50,25 +50,29 @@ void *map_domain_mem(unsigned long pa) spin_lock_irqsave(&map_lock, flags); /* Has some other CPU caused a wrap? We must flush if so. */ - if ( map_idx < shadow_map_idx[cpu] ) + if ( epoch != shadow_epoch[cpu] ) { perfc_incrc(domain_page_tlb_flush); local_flush_tlb(); + shadow_epoch[cpu] = epoch; } - for ( ; ; ) - { + do { idx = map_idx = (map_idx + 1) & (MAPCACHE_ENTRIES - 1); - if ( idx == 0 ) flush_all_ready_maps(); - if ( cache[idx] == 0 ) break; + if ( unlikely(idx == 0) ) + { + flush_all_ready_maps(); + perfc_incrc(domain_page_tlb_flush); + local_flush_tlb(); + shadow_epoch[cpu] = ++epoch; + } } + while ( cache[idx] != 0 ); cache[idx] = (pa & PAGE_MASK) | __PAGE_HYPERVISOR; spin_unlock_irqrestore(&map_lock, flags); - shadow_map_idx[cpu] = idx; - va = MAPCACHE_VIRT_START + (idx << PAGE_SHIFT) + (pa & ~PAGE_MASK); return (void *)va; } -- 2.30.2